#pragma once
#include <string>
#include <filesystem> // C++17
#include <map>
#include <stdexcept>
#include <type_traits>
#include <algorithm>
#include <cctype>   
class Config
{
public:
    static Config &getInstance();

    /**
     * @brief 获取指定类型的配置值。
     * @tparam T 要获取的值的类型 (int, double, bool, std::string 等)。
     * @param section 配置项所在的节（section）。
     * @param key 配置项的键（key）。
     * @param defaultValue 如果找不到对应的配置项，则返回此默认值。
     * @return T 找到的配置值或默认值。
     */
    template <typename T>
    T GetValue(const std::string &key, const T &defaultValue) const;

    void setDefaultConfig();

private:
    Config();
    void parse();
    void trim(std::string &str);

    static std::string initialize_filepath()
    {
        std::filesystem::path exe_dir = std::filesystem::path(".");
#ifdef _WIN32
        return (exe_dir / "config" / "db.ini").string();
#else
        return (exe_dir / "config" / "db.conf").string();
#endif
    }

    bool is_init = false;
    static std::string m_filepath;
    std::map<std::string, std::string> m_data;
};

// --- 模板函数的实现需要放在头文件中 ---

template <typename T>
T Config::GetValue(const std::string &key, const T &defaultValue) const
{
    // 查找键（key）
    auto key_it = m_data.find(key);
    if (key_it == m_data.end())
    {
        return defaultValue;
    }

    const std::string &value_str = key_it->second;

    // 使用 C++17 的 if constexpr 进行类型安全的字符串转换
    try
    {
        if constexpr (std::is_same_v<T, std::string>)
        {
            return value_str;
        }
        else if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>)
        {
            // 适用于 int, long, short, etc.
            return static_cast<T>(std::stoll(value_str));
        }
        else if constexpr (std::is_floating_point_v<T>)
        {
            // 适用于 float, double
            return static_cast<T>(std::stod(value_str));
        }
        else if constexpr (std::is_same_v<T, bool>)
        {
            std::string lower_val = value_str;
            std::transform(lower_val.begin(), lower_val.end(), lower_val.begin(),
                           [](unsigned char c)
                           { return std::tolower(c); });
            if (lower_val == "true" || lower_val == "1" || lower_val == "yes" || lower_val == "on")
            {
                return true;
            }
            if (lower_val == "false" || lower_val == "0" || lower_val == "no" || lower_val == "off")
            {
                return false;
            }
            // 如果是其他无法识别的字符串，则认为转换失败
            throw std::invalid_argument("Cannot convert to bool");
        }
    }
    catch (const std::exception &)
    {
        // 如果字符串转换失败 (例如，试图将 "abc" 转为 int)
        // 返回默认值是更安全的行为
        return defaultValue;
    }

    // 如果类型不支持，编译时会报错
    return defaultValue;
}